package com.ssgz.sso.config;

import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ISet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

/**
 * 集群分组配置
 * 协助 nginx 完成灰度发布
 */
@Configuration
public class ClusterConfig {

    public static final String CLUSTER_SERVER_GROUP = "cluster:server:group";
    public static final String CLUSTER_SERVER_GROUP_ROUTE = "cluster:server:group:route";
    private static final Logger logger = LoggerFactory.getLogger(ClusterConfig.class);

    @Autowired
    HazelcastInstance hazelcastInstance;

    @Autowired
    ServerProperties serverProperties;

    @Value("${spring.application.name}")
    String appName;

    @Value("${spring.application.version}")
    String version;

    @Value("${spring.application.group}")
    String group;

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE+ 10)
    public Filter deploymentFilter(){
        Filter filter = new GenericFilter() {

            @Override
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

                //todo 静态文件不处理，静态文件需要放入统一目录

                // 处理路由规则，按规则写cookie , nginx 再通过cookie 转发到相应的集群
                try {
                    Map<String,String> groupRoute = hazelcastInstance.getReplicatedMap(CLUSTER_SERVER_GROUP_ROUTE);
                    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
                    HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
                    HttpSession httpSession = httpServletRequest.getSession(false);
                    String router = null;
                    if(httpSession!=null){
                        String usercode = (String) httpSession.getAttribute("usercode");
                        String comcode = (String) httpSession.getAttribute("comcode");
                        //usercode 的优先级比comcode高

                        if(comcode!=null){
                            //格式 [comcode|usercode]:[match]:[group]
                            for (String key : groupRoute.keySet()) {
                                if(key.startsWith("comcode")
                                        && comcode.matches(key.replace("comcode:",""))){
                                    router = groupRoute.get(key);
                                    break;
                                }
                            }
                        }
                        if(usercode!=null){
                            //格式 [comcode|usercode]:[match]:[group]
                            for (String key : groupRoute.keySet()) {
                                if(key.startsWith("usercode")
                                        && usercode.matches(key.replace("usercode:",""))){
                                    router = groupRoute.get(key);
                                    break;
                                }
                            }
                        }
                    }

                    if(router!=null && !"".equals(router.trim())){
                        Cookie cookie = new Cookie("router-"+appName,router);
                        cookie.setPath("/");
                        cookie.setHttpOnly(true);
                        httpServletResponse.addCookie(cookie);
                    }
                    httpServletResponse.setHeader("versioninfo",appName+":"+version);
                    httpServletResponse.setHeader("clustergroup",group);
                } catch (Exception e) {
                    logger.error(e.getMessage(),e);
                } finally {
                    filterChain.doFilter(servletRequest, servletResponse);
                }
            }
        };
        return filter;
    }
}
